package com.ricchieri.manage.bean;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

import org.primefaces.event.FlowEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleModel;

import com.ricchieri.bean.TravelStatusBean;
import com.ricchieri.common.BusinessSettings;
import com.ricchieri.common.CustomScheduleEvent;
import com.ricchieri.filter.BasicFilter;
import com.ricchieri.filter.ScheduleCharterFilter;
import com.ricchieri.lazymodel.ScheduleLazyModel;
import com.ricchieri.lazymodel.TravelStatusScheduleLazyDataModel;
import com.ricchieri.model.MeanPayment;
import com.ricchieri.model.Operation;
import com.ricchieri.model.Reservation;
import com.ricchieri.model.ScheduleCharter;
import com.ricchieri.model.ScheduleCharterExpense;
import com.ricchieri.model.User;
import com.ricchieri.service.interf.IMeanPaymentService;
import com.ricchieri.service.interf.IOperationService;
import com.ricchieri.service.interf.IScheduleCharterExpenseTypeService;
import com.ricchieri.service.interf.IScheduleCharterService;
import com.ricchieri.service.interf.ITripService;
import com.ricchieri.service.interf.IUserService;
import com.ricchieri.util.DateUtil;
import com.ricchieri.util.FacesUtil;
import com.ricchieri.util.StringUtils;

@ManagedBean(name = "travelStatusMB")
@ViewScoped
public class TravelStatusManageBean extends GenericManageBean {
	private static final long serialVersionUID = -7001021047911879866L;

	@ManagedProperty(value = "#{TripService}")
	ITripService tripService;

	@ManagedProperty(value = "#{ScheduleCharterService}")
	IScheduleCharterService scheduleCharterService;
	
	@ManagedProperty(value = "#{ScheduleCharterExpenseTypeService}")
	IScheduleCharterExpenseTypeService scheduleCharterExpenseTypeService;
	
	@ManagedProperty(value = "#{MeanPaymentService}")
	IMeanPaymentService meanPaymentService;	
	
	@ManagedProperty(value = "#{OperationService}")
	IOperationService operationService;	
	
	@ManagedProperty(value = "#{UserService}")
	private IUserService userService;
	
	private Map<String, String> trips = null;
	private Map<String, String> scheduleCharterExpenseType = null;
	private Map<String, String> meanPayments = null;

	private ScheduleCharterFilter scheduleCharterFilter = new ScheduleCharterFilter();
	private ScheduleModel eventModel = new DefaultScheduleModel();
	private CustomScheduleEvent event = new CustomScheduleEvent();
	private ScheduleLazyModel scheduleLazyModel;
	private ScheduleCharter scheduleCharter;
	private String selectedScheduleCharterExpenseType;
	private ScheduleCharterExpense scheduleCharterExpense = new ScheduleCharterExpense();
	private List<ScheduleCharterExpense> expenses;
	private TravelStatusBean travelStatusBean;
	private final String TAB_CONFIRMATION = "confirmation";

	public void setTrips(Map<String, String> trips) {
		this.trips = trips;
	}

	public ITripService getTripService() {
		return tripService;
	}

	public void setTripService(ITripService tripService) {
		this.tripService = tripService;
	}

	public Map<String, String> getTrips() {
		if (trips == null) {
			trips = getTripService().getComboTrips();
		}

		return trips;
	}

	public CustomScheduleEvent getEvent() {
		return event;
	}

	public void setEvent(CustomScheduleEvent event) {
		this.event = event;
	}

	public void onEventSelect(SelectEvent selectEvent) {
		event = (CustomScheduleEvent) selectEvent.getObject();;
	}

	public ScheduleModel getEventModel() {
		return eventModel;
	}

	public void setEventModel(ScheduleModel eventModel) {
		this.eventModel = eventModel;
	}


	public IScheduleCharterService getScheduleCharterService() {
		return scheduleCharterService;
	}

	public void setScheduleCharterService(
			IScheduleCharterService scheduleCharterService) {
		this.scheduleCharterService = scheduleCharterService;
	}


	public ScheduleCharterFilter getScheduleCharterFilter() {
		return scheduleCharterFilter;
	}

	public void setScheduleCharterFilter(
			ScheduleCharterFilter scheduleCharterFilter) {
		this.scheduleCharterFilter = scheduleCharterFilter;
	}

	public ScheduleLazyModel getScheduleLazyModel() {

		if (scheduleLazyModel == null) {
			scheduleLazyModel = new TravelStatusScheduleLazyDataModel(
					getScheduleCharterService(), getScheduleCharterFilter(),
					getEventModel());
		}
		return scheduleLazyModel;
	}

	public void setScheduleLazyModel(ScheduleLazyModel scheduleLazyModel) {
		this.scheduleLazyModel = scheduleLazyModel;
	}

	public void changeTrip() {
		setScheduleLazyModel(null);
		setEventModel(new DefaultScheduleModel());
	}
	
	public void showTravelDetails(CustomScheduleEvent event) {
		scheduleCharter = event.getScheduleCharter();
		for (Reservation reservation : scheduleCharter.getActiveReservations()) {
			reservation.initStatus();
		}
	}

	public ScheduleCharter getScheduleCharter() {
		return scheduleCharter;
	}

	public void setScheduleCharter(ScheduleCharter scheduleCharter) {
		this.scheduleCharter = scheduleCharter;
	}

	public String getSelectedScheduleCharterExpenseType() {
		return selectedScheduleCharterExpenseType;
	}

	public void setSelectedScheduleCharterExpenseType(
			String selectedScheduleCharterExpenseType) {
		this.selectedScheduleCharterExpenseType = selectedScheduleCharterExpenseType;
	}

	public ScheduleCharterExpense getScheduleCharterExpense() {
		if(scheduleCharterExpense == null) {
			scheduleCharterExpense = new ScheduleCharterExpense();
		}
		return scheduleCharterExpense;
	}

	public void setScheduleCharterExpense(
			ScheduleCharterExpense scheduleCharterExpense) {
		this.scheduleCharterExpense = scheduleCharterExpense;
	}

	public IScheduleCharterExpenseTypeService getScheduleCharterExpenseTypeService() {
		return scheduleCharterExpenseTypeService;
	}

	public void setScheduleCharterExpenseTypeService(
			IScheduleCharterExpenseTypeService scheduleCharterExpenseTypeService) {
		this.scheduleCharterExpenseTypeService = scheduleCharterExpenseTypeService;
	}

	public Map<String, String> getScheduleCharterExpenseType() {
		if(scheduleCharterExpenseType == null) {
			scheduleCharterExpenseType = getScheduleCharterExpenseTypeService().getComboScheduleCharterExpenseType();
		}
		return scheduleCharterExpenseType;
	}

	public void setScheduleCharterExpenseType(
			Map<String, String> scheduleCharterExpenseType) {
		this.scheduleCharterExpenseType = scheduleCharterExpenseType;
	}	
	
	public List<ScheduleCharterExpense> getExpenses() {
		if(expenses == null) {
			expenses = new ArrayList<ScheduleCharterExpense>(scheduleCharter.getScheduleCharterExpense());
		}
		return expenses;
	}

	public void setExpenses(List<ScheduleCharterExpense> expenses) {
		this.expenses = expenses;
	}

	public void saveExpense() {
		
		if(scheduleCharterExpense.getAmount()<=0) {
			FacesUtil.addErrorMsg(getFormName().concat(":charterExpenseAmount"), "requiredAmount");
		} else {
			BasicFilter expenseTypeFilter = new BasicFilter();
			expenseTypeFilter.setId(Integer.valueOf(getSelectedScheduleCharterExpenseType()));
			scheduleCharterExpense.setScheduleCharterExpenseType(getScheduleCharterExpenseTypeService().getScheduleCharterExpenseTypeById(expenseTypeFilter));
			scheduleCharterExpense.setDate(new Date(System.currentTimeMillis()));
			getExpenses().add(scheduleCharterExpense);
			resetExpense();
		}
	}

	private String getFormName() {
		return "tripStatus";
	}
	
	public void resetExpense() {
		scheduleCharterExpense = new ScheduleCharterExpense();
		selectedScheduleCharterExpenseType = null;
	}
	
	public void deleteExpense(ScheduleCharterExpense expense) {
		getExpenses().remove(expense);
	}
	
	public IMeanPaymentService getMeanPaymentService() {
		return meanPaymentService;
	}

	public void setMeanPaymentService(
			IMeanPaymentService meanPaymentService) {
		this.meanPaymentService = meanPaymentService;
	}

	public Map<String, String> getMeanPayments() {
		if (meanPayments == null) {
			meanPayments = getMeanPaymentService().getComboMeanPayment();
		}
		return meanPayments;		
	}

	public void setMeanPayments(Map<String, String> meanPayment) {
		this.meanPayments = meanPayment;
	}	
	
	public void changeMeanPayment(Reservation reser) {
		if(reser.getPaymentStatus()) {
			BasicFilter meanPaymentFilter = new BasicFilter();
			meanPaymentFilter.setId(reser.getMeanPaymentStatusId());
			MeanPayment meanPayment = getMeanPaymentService().getMeanPaymentById(meanPaymentFilter);
			reser.getTravel().setMeanPayment(meanPayment);
		}
	}
	
	public String onFlowProcess(FlowEvent event) {  
		
		if(event.getNewStep().equals(this.TAB_CONFIRMATION)) {
			travelStatusBean = new TravelStatusBean(scheduleCharter, expenses);
		}
		return event.getNewStep();
	}

	public TravelStatusBean getTravelStatusBean() {
		return travelStatusBean;
	}

	public void setTravelStatusBean(TravelStatusBean travelStatusBean) {
		this.travelStatusBean = travelStatusBean;
	}
	
	public String saveTravelStatus() {
		
		getScheduleCharter().setScheduleCharterExpense(expenses);
		getScheduleCharter().setLastTravelUpdate(new Date(System.currentTimeMillis()));
		
		getScheduleCharterService().updateScheduleCharter(getScheduleCharter());
		
		Operation operationReservation;
		Operation paidOperation;
		String description = "";
		for (Reservation reservation : getScheduleCharter().getActiveReservations()) {
			operationReservation = new Operation();
			operationReservation.setAutomatic(Boolean.TRUE);
			operationReservation.setOperationDate(new Date(System.currentTimeMillis()));
			operationReservation.setOperationType(BusinessSettings.OPERATION_RESERVATION);
			operationReservation.setAmount(reservation.getCost());
			
			description = FacesUtil.getMessage("travelDate").concat(" : ").concat(DateUtil.formatDate(reservation.getScheduleCharter().getSchedule().getDate()));
			description = description.concat("\n").concat(FacesUtil.getMessage("travelTime")).concat(" : ").concat(DateUtil.formatTime(reservation.getScheduleCharter().getSchedule().getTime()));
			description = description.concat("\n").concat(FacesUtil.getMessage("tripOrientation")).concat(" : ").concat(reservation.getScheduleCharter().getTrip().getFormatTrip());
			
			operationReservation.setObservation(description);
			operationReservation.setUser(reservation.getUser());
			getOperationService().addOperation(operationReservation);
			
			if(reservation.getTravel() != null && 
					reservation.getTravel().getMeanPayment() != null &&
					!reservation.getTravel().getMeanPayment().getDescription().equals(BusinessSettings.MEAN_PAYMENT_CC)) {
				
				paidOperation = new Operation();
				paidOperation.setAutomatic(Boolean.TRUE);
				paidOperation.setOperationDate(new Date(System.currentTimeMillis()));
				paidOperation.setOperationType(BusinessSettings.OPERATION_PAID);
				paidOperation.setAmount(reservation.getCost());
				
				
				description = FacesUtil.getMessage("travelDate").concat(" : ").concat(DateUtil.formatDate(reservation.getScheduleCharter().getSchedule().getDate()));
				description = description.concat("\n").concat(FacesUtil.getMessage("travelTime")).concat(" : ").concat(DateUtil.formatTime(reservation.getScheduleCharter().getSchedule().getTime()));
				description = description.concat("\n").concat(FacesUtil.getMessage("tripOrientation")).concat(" : ").concat(reservation.getScheduleCharter().getTrip().getFormatTrip());
				
				paidOperation.setObservation(description);
				paidOperation.setUser(reservation.getUser());
				getOperationService().addOperation(paidOperation);
			} else if(!reservation.getMeanPayment().getDescription().equals(BusinessSettings.MEAN_PAYMENT_CC)) {
				User user = reservation.getUser();
				String blockMotive = user.getBlockMotive();
				String travel = this.formatDateTime(DateUtil.converToDate(reservation.getScheduleCharter().getSchedule().getDate(), reservation.getScheduleCharter().getSchedule().getTime()));
				travel = travel.concat(" ").concat(FacesUtil.getMessage("of")).concat(" ").concat(reservation.getScheduleCharter().getTrip().getFormatTrip());
				
				String penalty = reservation.getUser().getBlockMotive();
				if(StringUtils.isEmpty(penalty)) {
					blockMotive = FacesUtil.getMessage("defaultBlockMessage").concat(travel);
				} else {					
					blockMotive = penalty.concat(",").concat(travel);
				}
				user.setBlock(Boolean.TRUE);
				user.setBlockMotive(blockMotive);
				getUserService().updateUser(user);
			}
		}
		
		FacesUtil.addParametersFlash(BusinessSettings.KEY_SCHEDULE_CHARTER, getScheduleCharter());
		return BusinessSettings.SUCCESS;
	}

	public IOperationService getOperationService() {
		return operationService;
	}

	public void setOperationService(IOperationService operationService) {
		this.operationService = operationService;
	}

	public IUserService getUserService() {
		return userService;
	}

	public void setUserService(IUserService userService) {
		this.userService = userService;
	}
}